package com.alibaba.citrus.cr.mn.order.center.facade.function.impl;

import cn.hutool.core.date.StopWatch;
import com.alibaba.citrus.cr.b2b.trade.order.repository.OrderQueryServiceRepository;
import com.alibaba.citrus.cr.common.enums.ordercenter.OrderCategoryEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderStatusEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderTypeEnum;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.SetOrderTag;
import com.alibaba.citrus.cr.mn.order.center.common.util.AssertUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.MoneyUtils;
import com.alibaba.citrus.cr.mn.order.center.common.util.StopWatchUtils;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.FulfillmentOrderAbilityAdapter;
import com.alibaba.citrus.cr.mn.order.center.facade.adapter.WmsOrderAdapter;
import com.alibaba.citrus.cr.mn.order.center.facade.function.check.SalesOrderUpdateParamsBizCheck;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.AbstractOrderBizUpdateService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.OrderAtomUpdateService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.OrderBizUpdateService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.BeanConverter;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.OrderUpdateParamsConvertService;
import com.alibaba.cloud.retail.wms.api.constants.WmsOrderMainTypeEnum;
import com.alibaba.cloud.retail.wms.api.model.orders.common.WarehousingOrderDTO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crb2btradecenter.domain.order.dto.QueryByOrderBizIdsRequest;
import com.epoch.app.crb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.crb2btradecenter.sdo.OrderSDO;
import com.epoch.app.crb2btradecenter.sdo.ScItemSDO;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomUpdateRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomUpdateResponse;
import com.epoch.app.mnordercenter.orderbaserequest.OrderBizUpdateRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderBizUpdateResponse;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.common.constant.OrderFeaturesKey.*;

/**
 * @author zhangxiaorui
 * @ClassName SalesOrderBizCreateServiceImpl
 * @description: TODO
 * @date 2023/05/16 14:04
 * @version: 1.0
 */
@Service("salesOrderBizUpdateService")
public class SalesOrderBizUpdateServiceImpl extends AbstractOrderBizUpdateService implements OrderBizUpdateService<OrderBizUpdateRequest, OrderAtomUpdateRequest, OrderAtomUpdateResponse> {
    private static final Log log = Log.getLogger(SalesOrderBizUpdateServiceImpl.class);

    @Resource(name = "salesOrderAtomUpdateService")
    private OrderAtomUpdateService salesOrderAtomUpdateService;
    @Resource
    private OrderUpdateParamsConvertService orderUpdateParamsConvertService;
    @Resource
    private SalesOrderUpdateParamsBizCheck salesOrderUpdateParamsBizCheck;
    @Resource
    private OrderQueryServiceRepository orderQueryServiceRepository;
    @Resource
    private WmsOrderAdapter wmsOrderAdapter;
    @Resource
    private FulfillmentOrderAbilityAdapter fulfillmentOrderAbilityAdapter;

    @Override
    public void preHandleRequestParams(OrderBizUpdateRequest bizUpdateRequest) {
        if (Objects.isNull(bizUpdateRequest.getCheckCredit())) {
            bizUpdateRequest.setCheckCredit(Boolean.TRUE);
        }
        if (Objects.isNull(bizUpdateRequest.getCheckStock())) {
            bizUpdateRequest.setCheckStock(Boolean.TRUE);
        }
        if (OrderCategoryEnum.STOCK.getCode().equals(bizUpdateRequest.getOrderCategoryCode()) && Objects.isNull(bizUpdateRequest.getCheckCreditB())) {
            // F1-B-b订单默认校验B信贷
            bizUpdateRequest.setCheckCreditB(Boolean.TRUE);
        }
        if (Objects.isNull(bizUpdateRequest.getIsSubmit())) {
            bizUpdateRequest.setIsSubmit(Boolean.TRUE);
        }
        super.preHandleRequestParams(bizUpdateRequest);
    }

    @Override
    public void paramsInvalidCheck(OrderBizUpdateRequest bizBatchUpdateRequest) {
        StopWatchUtils.start("订单中心商业修改", "paramsInvalidCheck");
        salesOrderUpdateParamsBizCheck.paramsInvalidCheck(bizBatchUpdateRequest, new OrderBizUpdateResponse());
        StopWatchUtils.stop();
    }

    @Override
    public OrderAtomUpdateResponse assembleBizBaseInfo(OrderBizUpdateRequest request) {
        extracted(request);
        // 查询其他中心数据并进行回填
        return super.assembleBizBaseInfo(request);
    }

    @Override
    public OrderAtomUpdateResponse assembleBizBaseInfoNew(OrderBizUpdateRequest request, Map<String, Object> queryResponseMap) {
        extracted(request);
        // 查询其他中心数据并进行回填
        return super.assembleBizBaseInfoNew(request, queryResponseMap);
    }

    private void extracted(OrderBizUpdateRequest request) {
        log.info("SalesOrderBizUpdateServiceImpl#assembleBizBaseInfo before request={}", JSON.toJSONString(request));

        // 查询db订单数据，用来回填主单信息
        OrderSDO orderSDO = getOrderSDO(request, request.getSalesOrderNo(), true);
        if (Objects.isNull(orderSDO)) {
            throw new FunctionException("OC-01-001-01-16-016", "");
        }
        request.setOrderType(orderSDO.getOrderType());

        // F1-B-b订单特殊逻辑
        if (OrderCategoryEnum.STOCK.getCode().equals(request.getOrderCategoryCode())) {
            // 校验订单是否为分公司订单，不是的话直接返回异常
            if (!SalesOrderTypeEnum.companyOrderCodes().contains(orderSDO.getOrderType())) {
                throw new FunctionException("OC-01-001-01-16-016", "");
            }
            // 校验订单状态，F1-B-b订单只支持修改待提交状态
            if (!SalesOrderStatusEnum.BEFORE_SUBMIT.getCode().equals(orderSDO.getStatus())) {
                throw new FunctionException("OC-01-001-01-16-053");
            }

            // 查询关联的F-B订单信息
            OrderSDO groupOrderSDO = getOrderSDO(request, orderSDO.getRelationNo(), false);
            if (Objects.isNull(groupOrderSDO)) {
                throw new FunctionException("OC-01-001-01-16-016", "");
            }
            request.setGroupSalesOrganizationCode(groupOrderSDO.getOrganizationOutCode());
            request.setGroupCustomerCode(groupOrderSDO.getCustomerCode());
            request.setGroupShipToPartyCode(groupOrderSDO.getReceiveAddressCode());
        }

        // 回填主单数据
        if (StringUtils.isBlank(request.getShipToPartyCode())) {
            request.setShipToPartyCode(orderSDO.getReceiveAddressCode());
            request.setShipToPartyName(orderSDO.getReceiveDetailAddress());
        }
        if (StringUtils.isBlank(request.getExpectedDeliveryDate())) {
            request.setExpectedDeliveryDate(DateUtils.toDateStr(orderSDO.getCustomerExpectDate(), DateUtils.DATE_FORMAT));
        }
        if (StringUtils.isBlank(request.getDeliveryMethodCode())) {
            request.setDeliveryMethodCode(orderSDO.getTransportModeCode());
            request.setDeliveryMethodName(orderSDO.getTransportModeName());
        }
        if (StringUtils.isBlank(request.getCostCenterCode())) {
            request.setCostCenterCode(orderSDO.getCostCenter());
            request.setCostCenterName(orderSDO.getCostCenterName());
        }
        request.setOrderReasonCode(orderSDO.getCreateReason());
        request.setOrderReasonName(orderSDO.getCreateReasonName());
        request.setNote(orderSDO.getRemark());
        if (StringUtils.isBlank(request.getOutOrderNo())) {
            request.setOutOrderNo(orderSDO.getOuterOrderId());
        }
        if (StringUtils.isBlank(request.getBizFeatures())) {
            request.setBizFeatures(orderSDO.getBizFeatures());
        }
        if (StringUtils.isBlank(request.getSalesOrganizationCode())) {
            request.setSalesOrganizationCode(orderSDO.getOrganizationOutCode());
        }
        if (StringUtils.isBlank(request.getBusinessChannel())) {
            request.setBusinessChannel(orderSDO.getChannelCode());
        }
        if (StringUtils.isBlank(request.getCustomerCode())) {
            request.setCustomerCode(orderSDO.getCustomerCode());
        }
        if (StringUtils.isBlank(request.getProductGroupCode())) {
            request.setProductGroupCode(orderSDO.getProductGroupCode());
        }
        if (StringUtils.isBlank(request.getSalesDepartmentCode())) {
            request.setSalesDepartmentCode(orderSDO.getDepartmentOutCode());
            request.setSalesDepartmentName(orderSDO.getDepartmentName());
        }
        if (StringUtils.isBlank(request.getSalesChannelCode())) {
            request.setSalesChannelCode(orderSDO.getSaleChannelOutCode());
            request.setSalesChannelName(orderSDO.getSaleChannelName());
        }
        if (StringUtils.isBlank(request.getReceiveWarehouseCode())
                && StringUtils.isBlank(request.getReceiveFactoryCode())
                && StringUtils.isBlank(request.getReceiveStockCode())) {
            request.setReceiveWarehouseCode(orderSDO.getReceiveWareHouseOutCode());
            request.setReceiveFactoryCode(orderSDO.getReceiveFactoryCode());
            request.setReceiveStockCode(orderSDO.getReceiveStockCode());
        }
        if (StringUtils.isBlank(request.getFulfillmentTypeCode())) {
            request.setFulfillmentTypeCode(orderSDO.getFulfillmentTypeCode());
        }
        if (StringUtils.isBlank(request.getFulfillmentPriority())) {
            request.setFulfillmentPriority(orderSDO.getFulfillmentPriority());
        }
        if (StringUtils.isBlank(request.getAutoFulfillment())) {
            request.setAutoFulfillment(orderSDO.getAutoFulfillment());
        }

        Map<String, String> features = orderSDO.getFeatures();
        if (StringUtils.isBlank(request.getKaArea())) {
            request.setKaArea(features.get(KA_AREA));
        }
        if (StringUtils.isBlank(request.getKaSystem())) {
            request.setKaSystem(features.get(KA_SYSTEM));
        }
        if (StringUtils.isBlank(request.getSourceOrderTime())) {
            request.setSourceOrderTime(features.get(SOURCE_ORDER_TIME));
        }
        if (CollectionUtils.isEmpty(request.getOrderBizTag())) {
            request.setOrderBizTag(StringUtils.isBlank(orderSDO.getOrderBizTag()) ? null : Arrays.asList(orderSDO.getOrderBizTag().split(",")));
        }

        // 不允许修改的字段直接用db数据回填入参
        request.setStatus(orderSDO.getStatus());

        // 回填子单数据
        List<OrderLineSDO> orderLineSDOSList = orderSDO.getOrderLineSDOS();
        Map<String, OrderLineSDO> orderLineSDOMap = orderLineSDOSList.stream().collect(
                Collectors.toMap(k -> String.format("%s_%s_%s_%s_%s", orderSDO.getFromSys(), orderSDO.getBusinessType(), orderSDO.getBusinessUnitOutCode(), orderSDO.getOrderBizId(), k.getSerialNumber()), v -> v, (k1, k2) -> k1));
        request.getOrderDetails().forEach(orderDetail -> {
            if (StringUtils.isBlank(orderDetail.getLineNum())) {
                // 新增明细行
                // 空值校验
                AssertUtils.isTrue(StringUtils.isBlank(orderDetail.getSourceLineNum()), "OC-01-001-01-15-001", "来源单行号");
                AssertUtils.isTrue(StringUtils.isBlank(orderDetail.getProductCode()), "OC-01-001-01-15-001", "物料编码");
                AssertUtils.isTrue(StringUtils.isBlank(orderDetail.getProductQuantity()), "OC-01-001-01-15-001", "销售数量");
                if (SalesOrderTypeEnum.CASH_ORDER.equals(SalesOrderTypeEnum.of(orderSDO.getOrderType()))) {
                    AssertUtils.isTrue(StringUtils.isBlank(orderDetail.getManualTotalAmount()), "OC-01-001-01-15-001", "(销售公司现金销售订单)手工总金额");
                    AssertUtils.isAmountNumber(orderDetail.getManualTotalAmount(), true, "OC-01-001-01-15-006", "(销售公司现金销售订单)手工总金额");
                    AssertUtils.lengthCheck(orderDetail.getManualTotalAmount(), 10, true, "OC-01-001-01-15-004", "(销售公司现金销售订单)手工总金额");
                    AssertUtils.moneyCheck(orderDetail.getManualTotalAmount(), true, "OC-01-001-01-15-005", "(销售公司现金销售订单)手工总金额");
                    if (StringUtils.isNotBlank(orderDetail.getManualTotalAmount())) {
                        AssertUtils.isTrue(new BigDecimal("2147483647").compareTo(new BigDecimal(orderDetail.getManualTotalAmount())) < 0, "OC-01-001-01-15-009", "手工总金额", "最大2147483647");
                    }
                    BigDecimal manualPrice;
                    try {
                        BigDecimal totalAmount = new BigDecimal(orderDetail.getManualTotalAmount());
                        BigDecimal productQuantity = new BigDecimal(orderDetail.getProductQuantity());
                        manualPrice = totalAmount.divide(productQuantity);
                    } catch (Exception e) {
                        log.error("SalesOrderBizUpdateServiceImpl#assembleBizBaseInfo error", e);
                        throw new FunctionException("OC-01-001-01-15-006", "(新增行)手工总金额及销售数量");
                    }
                    orderDetail.setManualPrice(manualPrice.toPlainString());
                }

                // 长度校验
                AssertUtils.lengthCheck(orderDetail.getSourceLineNum(), 10, true, "OC-01-001-01-15-004", "来源单行号");
                AssertUtils.lengthCheck(orderDetail.getProductCode(), 50, true, "OC-01-001-01-15-004", "物料编码");
                AssertUtils.isWholeNumber(orderDetail.getProductQuantity(), true, "OC-01-001-01-15-009", "销售数量", "销售数量须为正整数");
                AssertUtils.lengthCheck(orderDetail.getProductQuantity(), 10, true, "OC-01-001-01-15-004", "销售数量");
                AssertUtils.isTrue(BigDecimal.ZERO.compareTo(new BigDecimal(orderDetail.getProductQuantity())) >= 0, "OC-01-001-01-15-009", "销售数量", "销售数量须为正整数");
                AssertUtils.isTrue(new BigDecimal("2147483647").compareTo(new BigDecimal(orderDetail.getProductQuantity())) < 0, "OC-01-001-01-15-009", "销售数量", "最大2147483647");

                if (OrderCategoryEnum.GROUP.getCode().equals(request.getOrderCategoryCode()) || OrderCategoryEnum.STOCK.getCode().equals(request.getOrderCategoryCode())) {
                    AssertUtils.isTrue(StringUtils.isBlank(orderDetail.getProductionDate()), "OC-01-001-01-15-001", "生产日期");
                    AssertUtils.lengthCheck(orderDetail.getProductionDate(), 10, true, "OC-01-001-01-15-004", "生产日期");
                }
            } else {
                // 修改明细行
                OrderLineSDO orderLineSDO = orderLineSDOMap.get(String.format("%s_%s_%s_%s_%s", request.getFromSys(), request.getBusinessType(), request.getBusinessUnitCode(), request.getSalesOrderNo(), orderDetail.getLineNum()));
                if (Objects.isNull(orderLineSDO)) {
                    throw new FunctionException("OC-01-001-01-16-017", orderDetail.getLineNum());
                }
                orderDetail.setSourceLineNum(orderLineSDO.getSourceLineNum());

                ScItemSDO scItemSDO = orderLineSDO.getScItemSDO();
                if (StringUtils.isBlank(orderDetail.getInnerProductCode())) {
                    orderDetail.setInnerProductCode(scItemSDO.getInnerProductCode());
                    orderDetail.setInnerProductName(scItemSDO.getInnerProductName());
                }
                if (StringUtils.isBlank(orderDetail.getProductionDate())) {
                    orderDetail.setProductionDate(DateUtils.formatDate(orderLineSDO.getProductationTime()));
                }
                if (StringUtils.isBlank(orderDetail.getProductQuantity())) {
                    orderDetail.setProductQuantity(orderLineSDO.getQuantity());
                }
                if (Objects.nonNull(scItemSDO.getUnitPrice())) {
                    orderDetail.setUnitPrice(String.valueOf(scItemSDO.getUnitPrice()));
                    orderDetail.setTotalAmount(String.valueOf(Math.multiplyExact(Long.parseLong(orderDetail.getProductQuantity()), scItemSDO.getUnitPrice())));
                }
                if (Objects.nonNull(scItemSDO.getActivityPrice())) {
                    orderDetail.setActivityPrice(String.valueOf(scItemSDO.getActivityPrice()));
                    orderDetail.setActivityTotalAmount(String.valueOf(Math.multiplyExact(Long.parseLong(orderDetail.getProductQuantity()), scItemSDO.getActivityPrice())));
                }
                if (StringUtils.isBlank(orderDetail.getStockConversionNum())) {
                    orderDetail.setStockConversionNum(orderLineSDO.getStockConversionNum());
                }
                if (StringUtils.isBlank(orderDetail.getSalesUnitCode())) {
                    orderDetail.setSalesUnitCode(scItemSDO.getSaleUnit());
                    orderDetail.setSalesUnitName(scItemSDO.getSaleUnitName());
                }
                if (StringUtils.isBlank(orderDetail.getShippingWarehouseCode())
                        && StringUtils.isBlank(orderDetail.getDeliveryFactoryCode())
                        && StringUtils.isBlank(orderDetail.getStockCode())) {
                    orderDetail.setShippingWarehouseCode(orderLineSDO.getShippingWarehouseOutCode());
                    orderDetail.setShippingWarehouseName(orderLineSDO.getShippingWarehouseName());
                    orderDetail.setDeliveryFactoryCode(orderLineSDO.getDeliveryFactoryCode());
                    orderDetail.setDeliveryFactoryName(orderLineSDO.getDeliveryFactoryName());
                    orderDetail.setStockCode(orderLineSDO.getStockCode());
                    orderDetail.setStockName(orderLineSDO.getStockName());
                }
                if (StringUtils.isBlank(orderDetail.getUnitConversionRelationship())) {
                    orderDetail.setUnitConversionRelationship(scItemSDO.getUnitConvert());
                }
                orderDetail.setNote(orderLineSDO.getRemark());
                if (StringUtils.isBlank(orderDetail.getBizFeatures())) {
                    orderDetail.setBizFeatures(orderLineSDO.getBizFeatures());
                }
                if (SalesOrderTypeEnum.CASH_ORDER.equals(SalesOrderTypeEnum.of(orderSDO.getOrderType()))) {
                    if (StringUtils.isBlank(orderDetail.getManualTotalAmount())) {
                        orderDetail.setManualPrice(MoneyUtils.moneyFen2Yuan(orderLineSDO.getManualPrice()));
                        orderDetail.setManualTotalAmount(MoneyUtils.moneyFen2Yuan(orderLineSDO.getManualTotalAmount()));
                    } else {
                        BigDecimal manualPrice;
                        try {
                            BigDecimal totalAmount = new BigDecimal(orderDetail.getManualTotalAmount());
                            BigDecimal productQuantity = new BigDecimal(orderDetail.getProductQuantity());
                            manualPrice = totalAmount.divide(productQuantity);
                        } catch (Exception e) {
                            log.error("SalesOrderBizUpdateServiceImpl#assembleBizBaseInfo error", e);
                            throw new FunctionException("OC-01-001-01-15-006", "手工总金额及销售数量");
                        }
                        orderDetail.setManualPrice(manualPrice.toPlainString());
                    }
                } else {
                    AssertUtils.isTrue(StringUtils.isNotBlank(orderDetail.getManualTotalAmount()), "OC-01-001-01-15-009", "手工总金额", "非(销售公司现金销售订单)不能有值");
                }
                if (StringUtils.isBlank(orderDetail.getConfirmQuantity())) {
                    orderDetail.setConfirmQuantity(orderLineSDO.getConfirmQuantity());
                }
                // 修改明细行时不允许修改的字段直接用db数据回填入参
                orderDetail.setProductCode(scItemSDO.getScItemOutCode());
                orderDetail.setProductName(scItemSDO.getScItemTitle());
                orderDetail.setActivityId(orderLineSDO.getActivityCode());
                orderDetail.setActivityLineNo(orderLineSDO.getActivityTermId());
                orderDetail.setRefuseReasonName(orderLineSDO.getRefuseReasonName());
                orderDetail.setOutLineNum(orderLineSDO.getOuterOrderLineId());
                orderDetail.setReceiveWarehouseCode(orderLineSDO.getReceiveWarehouseOutCode());
                orderDetail.setReceiveWarehouseName(orderLineSDO.getReceiveWarehouseName());
                orderDetail.setReceiveStockCode(orderLineSDO.getReceiveStockCode());
                orderDetail.setReceiveStockName(orderLineSDO.getReceiveStockName());
                orderDetail.setReceiveFactoryCode(orderLineSDO.getReceiveFactoryCode());
                orderDetail.setReceiveFactoryName(orderLineSDO.getReceiveFactoryName());
                orderDetail.setStockUnitCode(scItemSDO.getInventoryUnitCode());
                orderDetail.setStockUnitName(scItemSDO.getInventoryUnitName());
                // TODO 0125 买赠标识/产品条码
            }
        });
        log.info("SalesOrderBizUpdateServiceImpl#assembleBizBaseInfo after request={}", JSON.toJSONString(request));

        // 补充明细行的修改信息，数据不全会导致后面仓库和库存校验失败
//        orderUpdateParamsConvertService.convert(request, SetOrderTag.NORMAL);
        Result<String> result = orderUpdateParamsConvertService.checkWarehouseAndProduct(request);
        if (!result.isSuccess()) {
            throw new FunctionException(result.getErrorCode(), result.getMessage());
        }
    }

    private OrderSDO getOrderSDO(OrderBizUpdateRequest orderBizUpdateRequest, String saleOrderNo, boolean needLines) {
        QueryByOrderBizIdsRequest queryByOrderBizIdsRequest = QueryByOrderBizIdsRequest.builder()
                .fromSys(orderBizUpdateRequest.getFromSys())
                .businessType(Integer.valueOf(orderBizUpdateRequest.getBusinessType()))
                .businessUnitOutCode(orderBizUpdateRequest.getBusinessUnitCode())
                .orderBizIds(Collections.singletonList(saleOrderNo))
                .build();
        List<OrderSDO> orderSDOList = orderQueryServiceRepository.queryByOrderBizIds(queryByOrderBizIdsRequest, needLines);
        if (CollectionUtils.isEmpty(orderSDOList) || !orderBizUpdateRequest.getOrderCategoryCode().equals(orderSDOList.get(0).getOrderCategoryCode())) {
            throw new FunctionException("OC-01-001-01-16-016", "");
        }
        return orderSDOList.get(0);
    }

    @Override
    public OrderAtomUpdateRequest convertAtomRequest(OrderBizUpdateRequest updateRequest) {
        OrderAtomUpdateRequest atomUpdateRequest = new OrderAtomUpdateRequest();
        BeanConverter.convert(updateRequest, atomUpdateRequest);
        return atomUpdateRequest;
    }

    @Override
    public OrderAtomUpdateResponse processAtomAbility(OrderAtomUpdateRequest atomCreateRequest, OrderAtomUpdateResponse responses) {
        // 非空时异常直接返回
        if (Objects.isNull(responses)) {
            responses = salesOrderAtomUpdateService.update(atomCreateRequest);
            log.info("修改销售订单原子能力返回结果 Request={}, Result={}",
                    JSON.toJSONString(atomCreateRequest), JSONArray.toJSONString(responses));
        }
        return responses;
    }

    @Override
    public String getOrderTag() {
        return SetOrderTag.NORMAL;
    }

    @Override
    public OrderAtomUpdateResponse updateWithBeforeDelivery(OrderBizUpdateRequest request) {
        try {
            log.info("SalesOrderBizUpdateServiceImpl#updateWithBeforeDelivery request:{}", JSON.toJSONString(request));
            StopWatchUtils.start("F-B销售订单待交货修改", "paramsInvalidCheck");
            paramsInvalidCheck(request);
            StopWatchUtils.stop();
            StopWatchUtils.start("F-B销售订单待交货修改", "preHandleRequestParams");
            preHandleRequestParams(request);
            StopWatchUtils.stop();
            StopWatchUtils.start("F-B销售订单待交货修改", "assembleBizBaseInfoNew");
            OrderAtomUpdateResponse responses = assembleBizBaseInfoNew(request, Maps.newConcurrentMap());
            StopWatchUtils.stop();
            if (Objects.nonNull(responses)) {
                return responses;
            }

            StopWatchUtils.start("F-B销售订单待交货修改", "wmsOrderCheck");
            log.info("SalesOrderBizUpdateServiceImpl#updateWithBeforeDelivery assemble after request:{}", JSON.toJSONString(request));
            OrderAtomUpdateRequest atomUpdateRequest = convertAtomRequest(request);
            log.info("SalesOrderBizUpdateServiceImpl#updateWithBeforeDelivery atomUpdateRequest:{}", JSON.toJSONString(atomUpdateRequest));
            responses = new OrderAtomUpdateResponse();
            // 需要 校验出库单是否存在和关闭履约单
            List<WarehousingOrderDTO> warehousingOrderDTOList = wmsOrderAdapter.queryWmsOrderByOtherOrder(request.getSalesOrderNo());
            log.info("SalesOrderBizUpdateServiceImpl#updateWithBeforeDelivery warehousingOrderDTOList={}", JSON.toJSONString(warehousingOrderDTOList));
            for (WarehousingOrderDTO warehousingOrderDTO : warehousingOrderDTOList) {
                boolean out = WmsOrderMainTypeEnum.OUT.getValue().equals(warehousingOrderDTO.getMainOrderType())
                        || WmsOrderMainTypeEnum.SALES_OUT.getValue().equals(warehousingOrderDTO.getMainOrderType())
                        || WmsOrderMainTypeEnum.OTHER_OUT.getValue().equals(warehousingOrderDTO.getMainOrderType());
                if (out && org.apache.commons.collections.CollectionUtils.isNotEmpty(warehousingOrderDTO.getWmsSubOrders())) {
                    responses = OrderAtomUpdateResponse.builder().errorCode("OC-01-001-01-16-013").message("该销售订单已存在出库单，不允许更改").salesOrderNo(request.getSalesOrderNo()).build();
                    return responses;
                }
            }
            StopWatchUtils.stop();
            StopWatchUtils.start("F-B销售订单待交货修改", "fulfillmentOrderCheck");
            responses = fulfillmentOrderAbilityAdapter.cancelOrderInner(request.getSalesOrderNo(), request.getModifierName());
            if (Objects.nonNull(responses)) {
                return responses;
            }
            StopWatchUtils.stop();
            StopWatchUtils.start("F-B销售订单待交货修改", "submitSaveTransactionalNew");
            log.info("SalesOrderBizUpdateServiceImpl#updateWithBeforeDelivery submitSaveTransactionalNew atomUpdateRequest:{}", JSON.toJSONString(atomUpdateRequest));
            salesOrderAtomUpdateService.submitSaveTransactionalNew(atomUpdateRequest, responses);
            StopWatchUtils.stop();
            StopWatchUtils.print("SalesOrderBizUpdateServiceImpl#updateWithBeforeDelivery");
            return responses;
        } catch (Exception e) {
            log.error("SalesOrderBizUpdateServiceImpl#updateWithBeforeDelivery error", e);
            throw e;
        }

    }
}
